/* @LICENSE(NICTA_CORE) */

#include <sel4/sel4.h>

/* 
 * __aeabi_read_tp returns a pointer to the TLS segment (for the initial
 * exec TLS model), which is placed immediately after the IPC buffer.
 * It is defined naked because it doesn't use normal calling conventions -
 * in particular, r1-r3 must be preserved - but it can't be defined in plain
 * asm because it needs sizeof.
 * The return type is actually void*, but is declared void to avoid a compiler 
 * warning. (Well done, gcc.)
 */
void __aeabi_read_tp(void) __attribute__((naked));
void __aeabi_read_tp(void)
{
    asm volatile (
        "mov    r0, %0\n"
        "rsb    r0, r0, #0\n"
        "ldr    r0, [r0]\n"
        "add    r0, r0, %1\n"
        "mov    pc, lr\n"
        :: "i" (-seL4_GlobalsFrame), "i" (sizeof(seL4_IPCBuffer))
    );
}
